#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from string import atoi,atof
from ClusterUtility import dotproduct

_DEBUG = False
#_DEBUG = True

def PrintUsageInfo():
    print("Usage: python Perceptron.py <train-file> -C <value> -N <Number_of_classes>")

"""
@desc :采用感知器法对数据进行分类
@data :数据样品
@C :参数，控制迭代
"""
def MultiPerceptronClassifier(dataset, C, N):
    #为每一个类都分配一个权值
    attrnum = len(dataset[0]) - 1 #减去分类信息的最后一位
    w = [0] * attrnum
    weight = []
    for i in range(0, N):
        weight.append([0]*attrnum)
    k = 1 #迭代次数
    while 1:
        for data in dataset:
            flag = True
            c = int(data[-1])
            assert(c>=0 and c<N)
            pmax = dotproduct(weight[c], data[0:-1]) #data[0:-1]不包含data[-1]
            for i in range(0, N):
                if i == c:
                    continue #不考虑本数据
                p = dotproduct(weight[i], data[0:-1])
                if p >= pmax:
                    flag = False
                    #调整权值
                    for j in range(0, attrnum):
                        weight[i][j] = weight[i][j] - C * data[j]
            if not flag:
                for j in range(0, attrnum):
                    weight[c][j] = weight[c][j] + C * data[j]
            print("迭代次数：%d" % k)
            k = k + 1
            print(weight)
        if flag:
            break
    print("训练结果：")
    print(weight)

# 初始化参数和训练数据
def init(argv):
    if len(argv) < 2:
        PrintUsageInfo()
        return 
    else:
        C = 1
        N = 0
        filepath = argv[1]
        print("数据文件：" + filepath)
        # 解析参数C
        for i in range(2,len(argv)):
            if "-C" == argv[i]:
                if i+1 < len(argv):
                    C = atof(argv[i+1])
                    i = i + 1
                    print("C = %d" % C)
                else:
                    print("-C <value> : <value> can't be empty!")
                    exit(1)
            if "-N" == argv[i]:
                if i+1 < len(argv):
                    N = atoi(argv[i+1])
                    i = i + 1
                    print("N = %d" % N)
                else:
                    print("-N <value> : <value> can't be empty!")
                    exit(1)
    if N == 0:
        PrintUsageInfo()
        exit(0)
    #从数据文件中读取样品数据
    f = open(filepath,"r") #open data file
    dataset = []
    for line in f:
        if line[0] == '#': #ignore strings that start with "#"
            continue
        sample = line.split(" ")
        data = []
        for attr in sample:
            data.append(atof(attr))
        #产生增广向量,并将最后一位放置为分类信息
        c =  data[-1]
        data[-1] = 1
        data.append(c)
        print(data)
        dataset.append(data)
    #train the classifier
    MultiPerceptronClassifier(dataset, C, N)

if __name__ == "__main__":
    if _DEBUG == True: 
        import pdb 
        pdb.set_trace()     
    init(sys.argv)
